unit DImp.Scene;

interface

uses
  DIrr.Types, DIrr.Structs, DIrr.Scene, DIrr.Matrix4, DIrr.Vector3D, DIrr.Event,
  DIrr.Video, DIrr.Dimension2d, DIrr.Base;

type
  TPerspectiveCameraSceneNode = class(TCameraSceneNode)
  private
    FFovy: F32;       // Field of view
    FAspect: F32;     // Aspect ratio
    FZNear: F32;      // Value of the new view-plane
    FZFar: F32;       // Z-value of the far view-plane

    FTarget: TVector3DF;
    FUpVector: TVector3DF;

    FViewArea: SViewFrustum;
    FAffector: TMatrix4F;

    FInputReceiverEnabled: Boolean;
    FTargetAndRotationAreBound: Boolean;
  private
    procedure RecalculateProjectionMatrix;
    procedure RecalculateViewArea;
  public
    procedure SetPos(const Position: TVector3DF);
    procedure SetLookat(const Position: TVector3DF);
    procedure Recalculate;
  public
    constructor Create(Parent: TSceneNode; Mgr: TSceneManager;
      ID: S32);
  public
    procedure SetProjectionMatrix(const Projection: TMatrix4F;
      Orthogonal: Boolean = False); override;

    function GetProjectionMatrix: PMatrix4F; override;

    function GetViewMatrix: PMatrix4F; override;

    procedure SetViewMatrixAffector(const Affector: TMatrix4F); override;

    function GetViewMatrixAffector: PMatrix4F; override;

    function OnEvent(const Event: SEvent): Boolean; override;

    procedure SetTarget(const Position: TVector3DF); override;

    procedure SetRotation(const Rotation: TVector3DF); override;

    function GetTarget: PVector3DF; override;

    procedure SetUpVector(const Position: TVector3DF); override;

    function GetUpVector: PVector3DF; override;

    function GetNearValue: F32; override;

    function GetFarValue: F32; override;

    function GetAspectRotatio: F32; override;

    function GetFOV: F32; override;

    procedure SetNearValue(zn: F32); override;

    procedure SetFarValue(zf: F32); override;

    procedure SetAspectRatio(Aspect: F32); override;

    procedure SetFOV(fovy: F32); override;

    function GetViewFrustum: PViewFrustum; override;

    procedure SetInputReceiverEnabled(Enabled: Boolean); override;

    function IsInputReceiverEnabled: Boolean; override;

    procedure BindTargetAndRotation(Bound: Boolean); override;

    function GetTargetAndRotationBinding: Boolean; override;
  end;

implementation

{ TPerspectiveCameraSceneNode }

procedure TPerspectiveCameraSceneNode.BindTargetAndRotation(Bound: Boolean);
begin


end;

constructor TPerspectiveCameraSceneNode.Create(Parent: TSceneNode; Mgr: TSceneManager;
  ID: S32);
var
  ADriver: TVideoDriver;
  TargetSize: TDimension2DU;
begin
  SetDName('TImpCameraSceneNode');

  // set default projection
  FFovy  := PI / 2.5;  // Field of view

  if Assigned(Mgr) then
    ADriver := TVideoDriver(Mgr.GetVideoDriver)
  else
    ADriver := nil;

  FAspect := 4.0 / 3.0;
  if Assigned(ADriver) then
  begin
    TargetSize := ADriver.GetCurrentRenderTargetSize^;
    FAspect := TargetSize.Width / TargetSize.Height;
  end;

  Recalculate;
end;

function TPerspectiveCameraSceneNode.GetAspectRotatio: F32;
begin

end;

function TPerspectiveCameraSceneNode.GetFarValue: F32;
begin

end;

function TPerspectiveCameraSceneNode.GetFOV: F32;
begin

end;

function TPerspectiveCameraSceneNode.GetNearValue: F32;
begin

end;

function TPerspectiveCameraSceneNode.GetProjectionMatrix: PMatrix4F;
begin
  Result := FViewArea.GetTransform(ETS_PROJECTION);
end;

function TPerspectiveCameraSceneNode.GetTarget: PVector3DF;
begin

end;

function TPerspectiveCameraSceneNode.GetTargetAndRotationBinding: Boolean;
begin

end;

function TPerspectiveCameraSceneNode.GetUpVector: PVector3DF;
begin

end;

function TPerspectiveCameraSceneNode.GetViewFrustum: PViewFrustum;
begin

end;

function TPerspectiveCameraSceneNode.GetViewMatrix: PMatrix4F;
begin
  Result := FViewArea.GetTransform(ETS_VIEW);
end;

function TPerspectiveCameraSceneNode.GetViewMatrixAffector: PMatrix4F;
begin
  Result := @FAffector;
end;

function TPerspectiveCameraSceneNode.IsInputReceiverEnabled: Boolean;
begin

end;

function TPerspectiveCameraSceneNode.OnEvent(const Event: SEvent): Boolean;
var
  Anm: TSceneNodeAnimator;
begin
  if not FInputReceiverEnabled then
  begin
    Result := False;
    Exit;
  end;

  for Anm in FAnimators do
  begin
    //TSceneNodeAnimator(Anm)

  end;

end;

procedure TPerspectiveCameraSceneNode.Recalculate;
begin
  RecalculateProjectionMatrix;
  RecalculateViewArea;
end;

procedure TPerspectiveCameraSceneNode.RecalculateProjectionMatrix;
var
  MatrixPtr: PMatrix4F;
begin
  MatrixPtr := FViewArea.GetTransform(ETS_PROJECTION);
  MatrixPtr^.BuildProjectionMatrixPerspectiveFovLH(FFovy, FAspect, FZNear, FZFar);
end;

procedure TPerspectiveCameraSceneNode.RecalculateViewArea;
var
  m: TMatrix4F;
begin
  GetAbsolutePosition(FViewArea.CameraPosition);

  m.Init(imfNothing);
  m.SetByProductNoCheck(FViewArea.GetTransform(ETS_PROJECTION)^, FViewArea.GetTransform(ETS_VIEW)^);

  FViewArea.SetFrom(m);
end;

procedure TPerspectiveCameraSceneNode.SetAspectRatio(Aspect: F32);
begin


end;

procedure TPerspectiveCameraSceneNode.SetFarValue(zf: F32);
begin


end;

procedure TPerspectiveCameraSceneNode.SetFOV(fovy: F32);
begin


end;

procedure TPerspectiveCameraSceneNode.SetInputReceiverEnabled(Enabled: Boolean);
begin


end;

procedure TPerspectiveCameraSceneNode.SetLookat(const Position: TVector3DF);
begin

end;

procedure TPerspectiveCameraSceneNode.SetNearValue(zn: F32);
begin


end;

procedure TPerspectiveCameraSceneNode.SetPos(const Position: TVector3DF);
begin

end;

procedure TPerspectiveCameraSceneNode.SetProjectionMatrix(const Projection: TMatrix4F;
  Orthogonal: Boolean);
var
  MPtr: PMatrix4F;
begin
  FIsOrthogonal := Orthogonal;
  MPtr := FViewArea.GetTransform(ETS_PROJECTION);
  MPtr^ := Projection;
end;

procedure TPerspectiveCameraSceneNode.SetRotation(const Rotation: TVector3DF);
begin


end;

procedure TPerspectiveCameraSceneNode.SetTarget(const Position: TVector3DF);
begin


end;

procedure TPerspectiveCameraSceneNode.SetUpVector(const Position: TVector3DF);
begin


end;

procedure TPerspectiveCameraSceneNode.SetViewMatrixAffector(const Affector: TMatrix4F);
begin
  FAffector := Affector;
end;

end.
